package com.own.component.common.base.service.item;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.own.base.BaseResponseCode;
import com.own.component.common.base.entity.po.BaseBean;
import com.own.component.common.base.entity.vo.BaseBeanVo;
import com.own.component.common.em.BusinessEnum;

import java.util.function.Supplier;

/**
 * BaseGetService
 *
 * @author chenxueli
 * @date 2022-06-15 03:14:15
 */
public interface BaseGetService<
        PO extends BaseBean,
        VO extends BaseBeanVo<PO>
        > {

    /**
     * 根据id获取信息
     *
     * @param pk 主键id
     * @return 查询出的对象
     */
    default VO getById(Long pk) {
        return getById(pk, true);
    }

    /**
     * 根据id获取信息
     *
     * @param pk    主键id
     * @param check 是否验证为null
     * @return 查询出的对象
     */
    default VO getById(Long pk, boolean check) {
        return getById(pk, check, BusinessEnum.NOT_FOUND_OBJECT);
    }

    /**
     * 根据id获取信息
     *
     * @param pk           主键id
     * @param responseCode 错误消息
     * @return 查询出的对象
     */
    default VO getById(Long pk, BaseResponseCode responseCode) {
        return getById(pk, true, responseCode);
    }

    /**
     * 根据id获取信息
     *
     * @param pk           主键id
     * @param check        是否验证为null
     * @param responseCode 错误消息
     * @return 查询出的对象
     */
    default VO getById(Long pk, boolean check, BaseResponseCode responseCode) {
        return getById(pk, check, responseCode, null);
    }

    /**
     * 根据id获取信息
     *
     * @param pk          主键id
     * @param getFunction 获取对象的方法
     * @return 查询出的对象
     */
    default VO getById(Long pk, Supplier<PO> getFunction) {
        return getById(pk, false, null, getFunction);
    }

    /**
     * 根据id获取信息
     *
     * @param pk           主键id
     * @param check        是否验证为null
     * @param responseCode 错误消息
     * @param getFunction  获取对象的方法
     * @return 查询出的对象
     */
    VO getById(Long pk, boolean check, BaseResponseCode responseCode, Supplier<PO> getFunction);

    /**
     * 根据id获取信息
     *
     * @param keyExtractor 字段信息
     * @param fk           外键id
     * @param <R>          类型
     * @return 查询出的对象
     */
    default <R> VO getById(SFunction<PO, R> keyExtractor, Long fk) {
        return getById(keyExtractor, fk, true);
    }

    /**
     * 根据id获取信息
     *
     * @param keyExtractor 字段信息
     * @param fk           外键id
     * @param check        是否验证为null
     * @param <R>          类型
     * @return 查询出的对象
     */
    default <R> VO getById(SFunction<PO, R> keyExtractor, Long fk, boolean check) {
        return getById(keyExtractor, fk, check, BusinessEnum.NOT_FOUND_OBJECT);
    }

    /**
     * 根据id获取信息
     *
     * @param keyExtractor 字段信息
     * @param fk           外键id
     * @param responseCode 错误消息
     * @param <R>          类型
     * @return 查询出的对象
     */
    default <R> VO getById(SFunction<PO, R> keyExtractor, Long fk, BaseResponseCode responseCode) {
        return getById(keyExtractor, fk, true, responseCode);
    }

    /**
     * 根据id获取信息
     *
     * @param keyExtractor 字段信息
     * @param fk           外键id
     * @param check        是否验证为null
     * @param responseCode 错误消息
     * @param <R>          类型
     * @return 查询出的对象
     */
    default <R> VO getById(SFunction<PO, R> keyExtractor, Long fk, boolean check, BaseResponseCode responseCode) {
        return getById(keyExtractor, fk, check, responseCode, null);
    }

    /**
     * 根据id获取信息
     *
     * @param keyExtractor 字段信息
     * @param fk           外键id
     * @param getFunction  获取方法
     * @param <R>          类型
     * @return 查询出的对象
     */
    default <R> VO getById(SFunction<PO, R> keyExtractor, Long fk, Supplier<PO> getFunction) {
        return getById(keyExtractor, fk, false, null, getFunction);
    }

    /**
     * 根据id获取信息
     *
     * @param keyExtractor 字段信息
     * @param fk           外键id
     * @param check        是否验证为null
     * @param responseCode 错误消息
     * @param getFunction  获取方法
     * @param <R>          类型
     * @return 查询出的对象
     */
    <R> VO getById(SFunction<PO, R> keyExtractor, Long fk, boolean check, BaseResponseCode responseCode, Supplier<PO> getFunction);

    /**
     * 根据id获取信息
     *
     * @param pk 主键id
     * @return 查询出的对象
     */
    default PO getPoById(Long pk) {
        return getPoById(pk, true);
    }

    /**
     * 根据id获取信息
     *
     * @param pk    主键id
     * @param check 是否验证为null
     * @return 查询出的对象
     */
    default PO getPoById(Long pk, boolean check) {
        return getPoById(pk, check, BusinessEnum.NOT_FOUND_OBJECT);
    }

    /**
     * 根据id获取信息
     *
     * @param pk           主键id
     * @param check        是否验证为null
     * @param responseCode 错误消息
     * @return 查询出的对象
     */
    default PO getPoById(Long pk, boolean check, BaseResponseCode responseCode) {
        return getPoById(pk, check, responseCode, null);
    }

    /**
     * 根据id获取信息
     *
     * @param pk          主键id
     * @param getFunction 获取对象的方法
     * @return 查询出的对象
     */
    default PO getPoById(Long pk, Supplier<PO> getFunction) {
        return getPoById(pk, false, null, getFunction);
    }

    /**
     * 根据id获取信息
     *
     * @param pk           主键id
     * @param check        是否验证为null
     * @param responseCode 错误消息
     * @param getFunction  获取对象的方法
     * @return 查询出的对象
     */
    PO getPoById(Long pk, boolean check, BaseResponseCode responseCode, Supplier<PO> getFunction);


    /**
     * 根据id获取信息
     *
     * @param keyExtractor 字段信息
     * @param fk           外键id
     * @param <R>          类型
     * @return 查询出的对象
     */
    default <R> PO getPoById(SFunction<PO, R> keyExtractor, Long fk) {
        return getPoById(keyExtractor, fk, true);
    }

    /**
     * 根据id获取信息
     *
     * @param keyExtractor 字段信息
     * @param fk           外键id
     * @param check        是否验证为null
     * @param <R>          类型
     * @return 查询出的对象
     */
    default <R> PO getPoById(SFunction<PO, R> keyExtractor, Long fk, boolean check) {
        return getPoById(keyExtractor, fk, check, BusinessEnum.NOT_FOUND_OBJECT);
    }

    /**
     * 根据id获取信息
     *
     * @param keyExtractor 字段信息
     * @param fk           外键id
     * @param check        是否验证为null
     * @param responseCode 错误消息
     * @param <R>          类型
     * @return 查询出的对象
     */
    default <R> PO getPoById(SFunction<PO, R> keyExtractor, Long fk, boolean check, BaseResponseCode responseCode) {
        return getPoById(keyExtractor, fk, check, responseCode, null);
    }

    /**
     * 根据id获取信息
     *
     * @param keyExtractor 字段信息
     * @param fk           外键id
     * @param getFunction  获取对象的方法
     * @param <R>          类型
     * @return 查询出的对象
     */
    default <R> PO getPoById(SFunction<PO, R> keyExtractor, Long fk, Supplier<PO> getFunction) {
        return getPoById(keyExtractor, fk, false, null, getFunction);
    }

    /**
     * 根据id获取信息
     *
     * @param keyExtractor 字段信息
     * @param fk           外键id
     * @param check        是否验证为null
     * @param responseCode 错误消息
     * @param getFunction  获取对象的方法
     * @param <R>          类型
     * @return 查询出的对象
     */
    <R> PO getPoById(SFunction<PO, R> keyExtractor, Long fk, boolean check, BaseResponseCode responseCode, Supplier<PO> getFunction);

    /**
     * 根据查询wrapper查询一条数据
     *
     * @param wrapper 查询条件
     * @return 查询出的列表信息
     */
    PO getOneByWrapper(QueryWrapper<PO> wrapper);

    /**
     * 根据查询wrapper查询一条数据
     *
     * @param wrapper 查询条件
     * @return 查询出的列表信息
     */
    PO getOneByWrapper(LambdaQueryWrapper<PO> wrapper);

}
